#!/usr/bin/env python3
#somethingiswrong.py

import os, sys, pickle, psutil, shutil
sys.path.insert(0, r'/home/george/Projects/ISH')
import dialog
from gi.repository import Gtk
from time import localtime, strftime
from os.path import expanduser

home_dir = expanduser("~")

class Handler:
    # Exit app if window is closed. Traps the signal from GUI.
    def on_window4_destroy(self, *args):
        Gtk.main_quit(*args)

    # Exit app if abort
    def on_w4_btn_esc_pressed(self, abort):
        Gtk.main_quit(abort)

    def on_chooseapp_changed(self, combo):
        ''' Choose app to work with. '''
        app = combo.get_active_text()
        if app != None:
            global app_buffer
            app_buffer = ("%s" %app)
#            print (app_buffer) # Debug entry

    def get_app(self):
        ''' Get app to work with. '''
        if 'app_buffer' in globals():
            if app_buffer != '':
                return app_buffer
            else:
                dialog.error_message("Du måste välja vilket program du har problem med.")
        else:
            dialog.error_message("Du måste välja vilket program du har problem med.")

    def make_file(self, file_name, date):
        ''' Create a file with todays date.

        This so we don't force users to reset more then once per day.'''
        temp_path = home_dir + file_name
        file_object = open(temp_path, 'wb')
        pickle.dump(date, file_object)
        file_object.close()

    def get_file(self, file_name):
        ''' Get a file that shows when they reset there app last time. '''
        temp_path = home_dir + file_name
        if os.path.exists(temp_path):
            file_object = open(temp_path,'rb')
            date_restored = pickle.load(file_object)
            return date_restored
        else:
            return None
        
    def set_res_app(self, appname):
        ''' Set path to config files and systems prog name
        
        We want to kill the apps via name and remove there config-files.
        Maybe put this in another file, so it's easier to edit.
        '''
        # Dont forget to add appname in support.py around line 120(+)
        if "OpenOffice" in appname:
            xpath = home_dir + "/.openoffice"
            pname = "openoffice" # not tested
            return {'xpath':xpath, 'pname':pname}
        elif "Firefox" in appname:
            xpath = home_dir + "/.mozilla"
            pname = "firefox"      
#            pname = r"/usr/lib/firefox/firefox"
            return {'xpath':xpath, 'pname':pname}
        elif "Google Chrome" in appname:
            xpath = home_dir + "/.config/chromium"
            pname = "chromium-browser"
            return {'xpath':xpath, 'pname':pname}     
        elif "Gimp" in appname:
            xpath = home_dir + "/.gimp"
            pname = "gimp" # not tested
            return {'xpath':xpath, 'pname':pname}
        elif "InDesign" in appname:
            xpath = home_dir + "/.indesign"
            pname = "rdesktop" # not tested
            return {'xpath':xpath, 'pname':pname}
        elif "Audition" in appname:
            xpath = home_dir + "/.audition"
            pname = None # Cant kill Audition since its not running via this system
            return {'xpath':xpath, 'pname':pname}
        elif "Firstclass klienten" in appname:
            xpath = home_dir + "/Firstclass"
            pname = "fcc" # not tested
            return {'xpath':xpath, 'pname':pname}
        else: return None
            
    def kill_app(self, pname):
        print ("Trying to kill " + pname)
        for proc in psutil.process_iter():
            if proc.name == pname:
                print ("Process found")
                proc.kill()
            else: print ("Process not found")
        
    def rm_settings(self, xpath):
        if os.path.isdir(xpath):
            shutil.rmtree(xpath, ignore_errors=False, onerror=None)
        elif os.path.isfile(xpath):
            os.remove(xpath)

    def dothefix(self, appname):
        '''Try to close app and remove settings.
        '''
        res_app = self.set_res_app(appname)
        if res_app:
#            print ("Got process name: " + (res_app['pname'])) # Debug entry, gives error if (res_app['pname'])) is None
            if res_app['pname']: # To make sure pname is not empty (Audition).
                print ("Process name " + res_app['pname'] + " seems ok")
                self.kill_app(res_app['pname'])
            self.rm_settings(res_app['xpath'])

        else:
            dialog.error_message("Kunde inte återställa " + appname + ".\nNågot är fel. Kontakta IT-ansvarig.")
            sys.exit(1)

        appfile = "/.restored_" + appname
        self.make_file(appfile, (dialog.get_date()))              
        dialog.info_message(appname + " har återställts.\nGå tillbaka till " + appname + " och se om det löste problemet.\n\
\nOm problemet upprepas gör en ny felanmälan.")
        sys.exit(0)        

    def try2fix(self, appname):
        '''Checks if app has been restored and give options.
        '''
#        print (appname) # Debug entry           
        check_restored = "/.restored_" + appname
#        print (check_restored) # Debug entry
        date_restored = self.get_file(check_restored)

        if not (date_restored) == (dialog.get_date()):
            answer = self.cancel_message("Du har problem med " + appname + ".",
                                    "Innan du gör en felanmälan ska du alltid prova att återställa programmet.\n"\
+ appname + " kommer att stängas och återställas.\n\nVill du göra det nu?")

            if "ok" in [(answer)]:
                print (appname) # Sends appname back to support.py so we know the user choosed to reset (fix) the app
                self.dothefix(appname)
            else:
                dialog.error_message("Du kan inte göra en felanmälan innan du försökt lösa problemet själv.")

        else:
            # Ask if user want to reset the app again.
            again = self.cancel_message("Du har redan återställt " + appname + " idag.",\
"Du har redan återställt " + appname + " idag.\n"\
"Vill du göra en felanmälan (NEJ) eller prova att återställa igen (JA)?\n\nOm du väljer NEJ kommer du till ett formulär\ndär du kan göra en felanmälan.\n\n\
Om du väljer JA återställs " + appname + " igen.")
            if "ok" in [(again)]:
                print (appname) # Sends appname back to support.py so we know the user choosed to reset (fix) the app
                self.dothefix(appname)
            elif "cancel" in [(again)]:
                # Sends "mkcall" back to support.py.. Opens error_report.py
                print ("mkcall")
                Gtk.main_quit("mkcall")                  
            else:
                sys.exit(0)
               
    def on_w4_btn_ok_pressed(self, ok):
        '''Call try2fix-function with app name.
        
        If Annat or Skrivare, give a simpler form. -> error.py
        '''
        if self.get_app:
            app2fix = self.get_app()
#            print (app2fix) # Debug entry
            if app2fix:
                #if "Annat" or "Skrivare" in [(app2fix)]: # or doesnt work. Everything passes. How to test two strings in one statement?
                if "Annat" in [(app2fix)]: 
                    print ("otherapp") # Sends "otherapp" to support.py
                    Gtk.main_quit("otherapp")
                elif "Skrivare" in [(app2fix)]:
                    print ("otherapp")
                    Gtk.main_quit("otherapp")
                else:    
                    self.try2fix(app2fix)                                   
        else:
            dialog.error_message("Inget program valdes.. Något är fel. Avslutar.")
            sys.exit(1)

    def cancel_message(self, title, message):
        '''Create an info message dialog and display it modally to the user.
        
        We need to handle this message a bit different then the info message in dialog.py
        '''
#        print (message)  # Debug entry 
        dialog = Gtk.MessageDialog(None,
                                   Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
                                   Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, message)
        dialog.set_title(title)
        response = dialog.run()
#        print (response) # Debug entry
        dialog.destroy()
        if (response == Gtk.ResponseType.YES): 
            return ("ok")
        elif (response == Gtk.ResponseType.NO):
            return ("cancel")
        else: # Probably -4 DELETE_EVENT
            sys.exit(0)
      
    def __init__(self):
        '''Use GtkBuilder to build our interface from the XML file.
        
        We use the initialization of the Handler class to establish
        references to the widgets we'll need to work with in the callbacks for
        various signals. This is done using the XML file we created with Glade
        '''
        try:
            builder = Gtk.Builder()
            builder.add_from_file("somethingiswrong.glade") 
        except:
            dialog.error_message("Failed to load UI XML file: somethingiswrong.glade")
            sys.exit(1)        
        
        # get the widgets which will be referenced in callbacks
        self.window4 = builder.get_object("window4")        

        builder.connect_signals(self)

    def main(self):
        '''Run main application window
        
        Exit app if main win is closed (x:ed). Even if signal from GUI is missing.
        '''
        self.window4.connect("delete-event", Gtk.main_quit)
        self.window4.show()
        Gtk.main()
    
if __name__ == "__main__":
    smtwrong = Handler()
    smtwrong.main()
